import fs from 'fs';
import path from 'path';
import { execSync } from 'child_process';
import express from 'express';
import cron from 'node-cron';

// 配置部分
const config = {
    projectPath: 'C:\\Users\\li\\Desktop\\项目\\围棋网\\uniapp',
    giteeRepo: 'https://gitee.com/liyucheng369/weiqi-netuniapp.git',
    branch: 'main',
    logFile: './modification_log.json',
    port: 3006,
    cronSchedule: '* * * * *',
    gitUserName: 'liyucheng369',
    gitUserEmail: '823976085@qq.com'
};

// 修改方法集合
const modificationMethods = [
    (functionCode, functionName) => {
        const newParam = `newParam${Math.floor(Math.random() * 100)}`;
        return functionCode.replace(/(function\s+\w+\s*\([^)]*)/, `$1, ${newParam}`);
    },
    (functionCode, functionName) => {
        const vars = functionCode.match(/(let|const|var)\s+(\w+)/g) || [];
        if (vars.length > 0) {
            const randomVar = vars[Math.floor(Math.random() * vars.length)];
            const oldName = randomVar.split(/\s+/)[1];
            const newName = `renamed${Math.floor(Math.random() * 100)}`;
            return functionCode.replace(new RegExp(`\\b${oldName}\\b`, 'g'), newName);
        }
        return functionCode;
    },
    (functionCode, functionName) => {
        const lines = functionCode.split('\n');
        const insertIndex = Math.max(1, Math.floor(Math.random() * lines.length));
        lines.splice(insertIndex, 0, `    console.log("${functionName} executed");`);
        return lines.join('\n');
    }
];

// 日志系统
class Logger {
    constructor(logFile) {
        this.logFile = logFile;
        this.ensureLogFile();
    }

    ensureLogFile() {
        if (!fs.existsSync(this.logFile)) {
            fs.writeFileSync(this.logFile, JSON.stringify([], null, 2));
        }
    }

    log(operation, file, functionName, success = true, message = '') {
        const entry = {
            timestamp: new Date().toISOString(),
            operation,
            file,
            functionName,
            success,
            message
        };

        const logs = JSON.parse(fs.readFileSync(this.logFile, 'utf8'));
        logs.push(entry);
        fs.writeFileSync(this.logFile, JSON.stringify(logs, null, 2));
        console.log(`[${entry.timestamp}] ${operation} ${success ? '成功' : '失败'}: ${file} -> ${functionName} ${message}`);
    }

    getLogs(limit = 50) {
        const logs = JSON.parse(fs.readFileSync(this.logFile, 'utf8'));
        return logs.slice(-limit);
    }
}

// 主功能类
class CodeModifier {
    constructor(config) {
        this.config = config;
        this.logger = new Logger(config.logFile);
        this.lastRun = null;
        this.nextRun = null;
        this.isRunning = false;
        this.gitInitialized = false;

        // uni-app 常用函数名前缀
        this.functionPrefixes = [
            'handle', 'on', 'do', 'get', 'set', 'has', 'is', 'can',
            'load', 'save', 'create', 'update', 'delete', 'remove', 'clear',
            'fetch', 'request', 'send', 'receive', 'upload', 'download',
            'show', 'hide', 'open', 'close', 'start', 'stop', 'pause', 'resume',
            'validate', 'check', 'verify', 'filter', 'sort', 'search', 'find',
            'format', 'parse', 'convert', 'transform', 'encode', 'decode',
            'encrypt', 'decrypt', 'compress', 'decompress', 'generate', 'create',
            'init', 'setup', 'config', 'bind', 'unbind', 'attach', 'detach',
            'refresh', 'reset', 'restore', 'backup', 'export', 'import',
            'calculate', 'compute', 'analyze', 'process', 'execute', 'run'
        ];

        // uni-app 常用函数名后缀
        this.functionSuffixes = [
            'User', 'Data', 'List', 'Info', 'Detail', 'Item',
            'Form', 'Field', 'Input', 'Select', 'Button', 'Menu',
            'Page', 'View', 'Component', 'Dialog', 'Modal', 'Popup',
            'Image', 'Avatar', 'Icon', 'Text', 'Label', 'Title',
            'Table', 'Grid', 'Card', 'Panel', 'Box', 'Container',
            'Api', 'Service', 'Provider', 'Manager', 'Controller', 'Handler',
            'Util', 'Helper', 'Tool', 'Plugin', 'Extension', 'Module',
            'Config', 'Setting', 'Option', 'Preference', 'Profile', 'Account',
            'Auth', 'Login', 'Register', 'Token', 'Session', 'Permission',
            'File', 'Image', 'Video', 'Audio', 'Media', 'Resource',
            'Time', 'Date', 'Calendar', 'Timer', 'Clock', 'Schedule',
            'Number', 'String', 'Array', 'Object', 'Map', 'Set',
            'Error', 'Exception', 'Warning', 'Message', 'Notification', 'Alert',
            'Success', 'Failure', 'Result', 'Status', 'State', 'Progress'
        ];

        // uni-app 特定函数名
        this.uniAppSpecificFunctions = [
            'onLoad', 'onShow', 'onReady', 'onHide', 'onUnload', 'onPullDownRefresh',
            'onReachBottom', 'onPageScroll', 'onTabItemTap', 'onNavigationBarButtonTap',
            'onBackPress', 'onShareAppMessage', 'onShareTimeline', 'onAddToFavorites',
            'getApp', 'getCurrentPages', 'uni.navigateTo', 'uni.redirectTo', 'uni.reLaunch',
            'uni.switchTab', 'uni.navigateBack', 'uni.showModal', 'uni.showToast',
            'uni.request', 'uni.uploadFile', 'uni.downloadFile', 'uni.getStorage',
            'uni.setStorage', 'uni.getSystemInfo', 'uni.getLocation', 'uni.chooseImage',
            'uni.previewImage', 'uni.login', 'uni.getUserInfo', 'uni.requestPayment'
        ];

        // 中文提交信息选项
        this.commitTypes = ['运维', '开发', '修改', '功能', '优化', '更新', '修复', '测试', '调整', '重构'];
        this.commitActions = ['开发了', '添加了', '实现了', '创建了', '扩展了', '改进了', '优化了', '完成了', '调整了', '重构了'];
    }

    // 执行 Git 命令
    execGitCommand(command, options = {}) {
        try {
            return execSync(command, {
                cwd: this.config.projectPath,
                stdio: 'pipe',
                ...options
            }).toString().trim();
        } catch (error) {
            throw new Error(`Git命令失败: ${command}\n${error.stderr?.toString() || error.message}`);
        }
    }

    // 初始化 Git 仓库
    async initializeGitRepository() {
        if (this.gitInitialized) return true;

        try {
            // 设置全局 Git 配置
            this.execGitCommand(`git config --global user.name "${this.config.gitUserName}"`);
            this.execGitCommand(`git config --global user.email "${this.config.gitUserEmail}"`);

            // 设置本地 Git 配置
            this.execGitCommand(`git config user.name "${this.config.gitUserName}"`);
            this.execGitCommand(`git config user.email "${this.config.gitUserEmail}"`);

            // 检查是否是 Git 仓库
            try {
                this.execGitCommand('git status');
                console.log('Git仓库已存在');
            } catch {
                console.log('初始化新的Git仓库...');
                this.execGitCommand('git init');
                this.execGitCommand(`git remote add origin ${this.config.giteeRepo}`);
            }

            // 检查分支
            const branches = this.execGitCommand('git branch');
            if (!branches.includes(this.config.branch)) {
                this.execGitCommand(`git checkout -b ${this.config.branch}`);
            } else {
                this.execGitCommand(`git checkout ${this.config.branch}`);
            }

            // 创建初始提交
            try {
                this.execGitCommand('git add .');
                this.execGitCommand('git commit -m "初始提交: 由自动修改器创建"');
            } catch {
                // 如果已经有提交，忽略错误
            }

            this.gitInitialized = true;
            console.log('Git仓库初始化成功');
            return true;

        } catch (error) {
            console.error('Git初始化失败:', error.message);
            return false;
        }
    }

    // 查找所有代码文件
    findAllCodeFiles(dirPath, arrayOfFiles = []) {
        try {
            const files = fs.readdirSync(dirPath);
            files.forEach(file => {
                const fullPath = path.join(dirPath, file);
                try {
                    if (fs.statSync(fullPath).isDirectory()) {
                        if (!file.includes('node_modules') && !file.includes('.git')) {
                            this.findAllCodeFiles(fullPath, arrayOfFiles);
                        }
                    } else if (file.match(/\.(js|ts|vue)$/)) {
                        arrayOfFiles.push(fullPath);
                    }
                } catch (error) {
                    console.log(`跳过 ${fullPath}: ${error.message}`);
                }
            });
        } catch (error) {
            console.log(`读取目录错误 ${dirPath}: ${error.message}`);
        }
        return arrayOfFiles;
    }

    // 从文件中提取函数
    extractFunctions(code, fileExt) {
        const functions = [];
        if (!code) return functions;

        try {
            const reservedKeywords = new Set(['if', 'for', 'while', 'switch', 'try', 'catch']);

            const functionRegex = /(function\s+(\w+)|(const|let|var)\s+(\w+)\s*=\s*(async\s*)?\s*function|(const|let|var)\s+(\w+)\s*=\s*\([^)]*\)\s*=>|(\w+)\s*\([^)]*\)\s*{)/g;
            let match;

            while ((match = functionRegex.exec(code)) !== null) {
                let functionName = match[2] || match[4] || match[7] || match[8];
                if (!functionName || reservedKeywords.has(functionName)) continue;

                const startPos = match.index;
                let braceCount = 0;
                let endPos = startPos;
                let foundStart = false;

                for (let i = startPos; i < Math.min(startPos + 1000, code.length); i++) {
                    if (code[i] === '{') {
                        braceCount++;
                        foundStart = true;
                    }
                    if (code[i] === '}') braceCount--;
                    if (foundStart && braceCount === 0) {
                        endPos = i;
                        break;
                    }
                }

                if (endPos > startPos) {
                    functions.push({
                        name: functionName,
                        code: code.substring(startPos, endPos + 1),
                        start: startPos,
                        end: endPos + 1
                    });
                }
            }
        } catch (error) {
            console.log('提取函数错误:', error.message);
        }
        return functions;
    }

    // 生成 uni-app 风格的函数名
    generateRandomFunctionName(originalName) {
        // 50% 几率使用 uni-app 特定函数名
        if (Math.random() > 0.5 && this.uniAppSpecificFunctions.length > 0) {
            return this.uniAppSpecificFunctions[
                Math.floor(Math.random() * this.uniAppSpecificFunctions.length)
            ];
        }

        // 50% 几率生成组合函数名
        const prefix = this.functionPrefixes[Math.floor(Math.random() * this.functionPrefixes.length)];
        const suffix = this.functionSuffixes[Math.floor(Math.random() * this.functionSuffixes.length)];

        // 驼峰命名：handle + User -> handleUser
        return prefix + suffix.charAt(0).toUpperCase() + suffix.slice(1).toLowerCase();
    }

    // 生成中文提交信息
    generateChineseCommitMessage(functionName) {
        const randomType = this.commitTypes[Math.floor(Math.random() * this.commitTypes.length)];
        const randomAction = this.commitActions[Math.floor(Math.random() * this.commitActions.length)];

        // 如果是 uni-app 特定函数，生成相应的提交信息
        if (this.uniAppSpecificFunctions.includes(functionName)) {
            return `${randomType}: ${randomAction} ${functionName} 生命周期函数`;
        }

        return `${randomType}: ${randomAction} ${functionName} 方法`;
    }

    // 执行修改
    async modifyAndCommit() {
        if (this.isRunning) return;
        this.isRunning = true;
        this.lastRun = new Date();

        try {
            console.log('开始修改过程...');

            // 初始化 Git
            if (!await this.initializeGitRepository()) {
                throw new Error('Git初始化失败');
            }

            // 查找代码文件
            const codeFiles = this.findAllCodeFiles(this.config.projectPath);
            if (codeFiles.length === 0) throw new Error('未找到代码文件');

            // 选择文件和函数
            let functions = [];
            let randomFile = '';
            for (let i = 0; i < 3 && functions.length === 0; i++) {
                randomFile = codeFiles[Math.floor(Math.random() * codeFiles.length)];
                const fileContent = fs.readFileSync(randomFile, 'utf8');
                functions = this.extractFunctions(fileContent, path.extname(randomFile));
            }
            if (functions.length === 0) throw new Error('未找到函数');

            const randomFunction = functions[Math.floor(Math.random() * functions.length)];
            const newFunctionName = this.generateRandomFunctionName(randomFunction.name);

            // 修改并写入文件
            const fileContent = fs.readFileSync(randomFile, 'utf8');
            const newFileContent = fileContent + `\n\n// Auto-generated function\n${randomFunction.code.replace(new RegExp(`\\b${randomFunction.name}\\b`, 'g'), newFunctionName)}`;
            fs.writeFileSync(randomFile, newFileContent);

            // 生成中文提交信息
            const commitMessage = this.generateChineseCommitMessage(newFunctionName);

            // Git 操作
            this.execGitCommand('git add .');
            this.execGitCommand(`git commit -m "${commitMessage}"`);

            // 推送到远程
            try {
                this.execGitCommand(`git push -u origin ${this.config.branch}`);
            } catch {
                this.execGitCommand(`git push -f origin ${this.config.branch}`);
            }

            this.logger.log('修改', path.basename(randomFile), randomFunction.name, true, `添加了 ${newFunctionName}`);
            console.log('修改完成! 提交信息:', commitMessage);

        } catch (error) {
            this.logger.log('执行', '系统', 'N/A', false, error.message);
            console.error('错误:', error.message);
        } finally {
            this.isRunning = false;
        }
    }

    // 启动定时任务
    startScheduler() {
        console.log('启动调度器...');
        cron.schedule(this.config.cronSchedule, () => this.modifyAndCommit());
        this.startMonitorServer();
        setTimeout(() => this.modifyAndCommit(), 2000);
    }

    // 启动监控服务器
    startMonitorServer() {
        const app = express();
        app.get('/', (req, res) => {
            res.send(`
            <html><body>
                <h1>代码修改器监控 - uni-app 版本</h1>
                <p>状态: ${this.isRunning ? '运行中' : '空闲'}</p>
                <p>上次运行: ${this.lastRun ? this.lastRun.toLocaleString() : '从未运行'}</p>
                <p>uni-app 特定函数: ${this.uniAppSpecificFunctions.length} 个</p>
                <p>函数前缀: ${this.functionPrefixes.length} 个可用</p>
                <p>函数后缀: ${this.functionSuffixes.length} 个可用</p>
                <p>总组合数: ${this.functionPrefixes.length * this.functionSuffixes.length} 种可能的函数名</p>
            </body></html>
            `);
        });
        app.listen(this.config.port, () => {
            console.log(`监控服务器运行在 http://localhost:${this.config.port}`);
        });
    }
}

// 主程序
const modifier = new CodeModifier(config);
modifier.startScheduler();